package asteroids.scenes;

import java.util.ArrayList;
import java.util.List;

import asteroids.components.Asteroid;
import asteroids.components.Bullet;
import asteroids.components.SpaceShip;
import asteroids.components.Space;

import com.uqbar.vainilla.GameScene;
import com.uqbar.vainilla.colissions.CollisionDetector;

public class Level extends GameScene {

	private List<Asteroid> asteroids         = new ArrayList<Asteroid>();
	private List<Asteroid> asteroidsToShow   = new ArrayList<Asteroid>();
	private List<Asteroid> asteroidsToRemove = new ArrayList<Asteroid>();
	private List<Bullet>   bullets           = new ArrayList<Bullet>();
	private SpaceShip      spaceShip;
	private Space          space;
	
	private static final int BULLETS   = 1;
	private static final int ASTEROIDS = 8;
	
	public Level() {
		this.setSpaceShip(new SpaceShip());
		this.setSpace(new Space());
		this.setUpAsteroids();
		this.setUpBullets();
		
		this.addComponents(this.getSpace(), this.getSpaceShip());
		this.addComponents(this.getAsteroids());
	}

	private void setUpBullets() {
		for (int i = 0; i < BULLETS; i++)
			this.getBullets().add(new Bullet());
	}

	private void setUpAsteroids() {
		for (int i = 0; i < ASTEROIDS; i++)
			this.getAsteroids().add(new Asteroid());
	}
	
	public void addOneBulletToGame(double x, double y, SpaceShip ship) {
		if (!this.getBullets().isEmpty()) {
			Bullet aBullet = this.getBullets().get(0);
			this.getBullets().remove(aBullet);
			aBullet.takeBackToTheGame();
			aBullet.shoot(x, y, ship);
			this.addComponent(aBullet);
		}
	}
	
	public void removeBulletFromGame(Bullet aBullet) {
		aBullet.destroy();
		this.getBullets().add(aBullet);
	}
	
	public void updateBulletHitAsteroid(Bullet bullet) {
		for (Asteroid asteroid : this.getAsteroids()) {
			if (this.bulletCollidesWithAsteroid(asteroid, bullet) && !asteroid.isDestroyPending()) {
				this.removeBulletFromGame(bullet);
				asteroid.weaken();
			}
		}
		this.updateAsteroids();
	}

	private void updateAsteroids() {
		this.getAsteroids().removeAll(this.getAsteroidsToRemove());
		this.getAsteroidsToRemove().clear();
		this.getAsteroids().addAll(this.getAsteroidsToShow());
		this.getAsteroidsToShow().clear();
	}
	
	private boolean bulletCollidesWithAsteroid(Asteroid asteroid, Bullet bullet) {
		return CollisionDetector.INSTANCE.collidesCircleAgainstRect(
				bullet.getX(), bullet.getY(), bullet.getDiameter() / 2,
				asteroid.getX(), asteroid.getY(), asteroid.getAppearance().getWidth(), asteroid.getAppearance().getHeight());
	}
	
	public void removeAsteroid(Asteroid asteroid) {
		asteroid.destroy();
		this.getAsteroidsToRemove().add(asteroid);
	}
	
	public void divideAsteroid(Asteroid asteroid) {
		this.removeAsteroid(asteroid);
		this.createNewAsteroidBasedOn(asteroid, 50, 0.2);
		this.createNewAsteroidBasedOn(asteroid, 50, -0.2);
	}

	private void createNewAsteroidBasedOn(Asteroid asteroid, double speedBoost, double direction) {
		Asteroid newAsteroid = new Asteroid(
				asteroid.getX(),
				asteroid.getY(),
				asteroid.getResistance(),
				asteroid.getSpeed() + speedBoost,
				asteroid.getDirection() + direction
				);
		
		this.getAsteroidsToShow().add(newAsteroid);
		this.addComponent(newAsteroid);
	}
	
	public void explodeShip() {
		this.getSpaceShip().destroy();
	}
	
	public boolean isSpaceShipDestroyed() {
		return this.getSpaceShip().isDestroyPending();
	}
	
	public boolean isAllAsteroidsDestroyed() {
		return this.getAsteroids().isEmpty();
	}
	
	
	
	

	public SpaceShip getSpaceShip() {
		return spaceShip;
	}

	public void setSpaceShip(SpaceShip ship) {
		this.spaceShip = ship;
	}

	public Space getSpace() {
		return space;
	}

	public void setSpace(Space space) {
		this.space = space;
	}

	public List<Asteroid> getAsteroids() {
		return asteroids;
	}

	public List<Bullet> getBullets() {
		return bullets;
	}

	public List<Asteroid> getAsteroidsToShow() {
		return asteroidsToShow;
	}

	public List<Asteroid> getAsteroidsToRemove() {
		return asteroidsToRemove;
	}
}
